/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-5-7 上午10:57 Created by sky
 */
package com.jade.bss.base.provision.impl;

import java.util.Map;
import javax.ejb.TransactionAttribute;
import javax.inject.Named;

import com.jade.bss.base.BssException;
import com.jade.bss.base.provision.ProvisionContext;
import com.jade.bss.base.provision.ProvisionService;
import com.jade.framework.base.pattern.pipeline.Pipeline;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.annotation.Transactional;

/**
 * 业务流程处理实现，采用管道的方式来配置各个处理流程。
 *
 * @author sky
 * @version 1.0 13-5-7 上午10:57
 */
@Named ("bss_provisionService")
public class ProvisionServiceImpl
        implements ProvisionService
{
    protected Map<String, Pipeline<ProvisionContext, BssException>> pipelineMap;
    protected Log logger = LogFactory.getLog(ProvisionServiceImpl.class);

    public void setPipelineMap(Map<String, Pipeline<ProvisionContext, BssException>> pipelineMap)
    {
        this.pipelineMap = pipelineMap;
    }

    protected Pipeline<ProvisionContext, BssException> getPipeline(ProvisionContext context)
    {
        if (pipelineMap == null) {
            return null;
        }
        else {
            return pipelineMap.get(context.getType());
        }
    }

    /**
     * 在处理过程中，如果每一个处理阀门需要访问外部耗时的资源，要注意申明不需要事务。
     *
     * @param contextes 处理上下文，包括具体业务处理类型和业务参数等等。
     * @throws BssException 处理异常
     */
    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void provision(ProvisionContext... contextes)
            throws BssException
    {
        //根据业务操作获取处理的pipeline
        for (ProvisionContext context : contextes) {
            Pipeline<ProvisionContext, BssException> pipeline = getPipeline(context);
            if (pipeline == null) {
                logger.error("Can't get handle pipeline for " + context.getType());
                throw new BssException("err.bss.base.provision.pipeline_not_found", context.getType());
            }
            pipeline.handle(context);
        }
    }
}
